package com.wit.witmg.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wit.witmg.entity.*;
import com.wit.witmg.mapper.TDeliverMapper;
import com.wit.witmg.mapper.TOrderpMapper;
import com.wit.witmg.mapper.TProdstockMapper;
import com.wit.witmg.service.ITDeliverService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wit.witmg.service.ITDeliverpService;
import com.wit.witmg.service.ITOrderpService;
import com.wit.witmg.service.ITProdstockService;
import com.wit.witmg.util.ErrorCode;
import com.wit.witmg.util.JsonResult;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bob
 * @since 2025-02-18
 */
@Service
@RequiredArgsConstructor
public class TDeliverServiceImpl extends ServiceImpl<TDeliverMapper, TDeliver> implements ITDeliverService {
    final ITDeliverpService deliverpService;
    final TOrderpMapper orderpMapper;
    final TProdstockMapper prodsMapper;
    final ITProdstockService stockService;
    final ITOrderpService orderpService;

    @Override
    public Object add(HttpServletRequest request, String json, String prod) {
        //在订单界面，选择订单，填写发货数量oqt，点击“发货”，新增出库单；参数(json,prod),id为空表示新增，(同时根据prod数组新增销售出库单),同时要把订单分解表中的oqt+=oqt;在交付界面，选择未备货的出库单，填写装箱信息，点击“出库”，
        // 根据id修改出库单，当stat为1时，根据prod数组的bn查库存表，本次出库金额cost=qt*库存金额amount/库存数量qt，库存表金额amount-=本次出库金额cost；库存数量qt-=出库数量qt;锁库数pqt-出库数量qt;出库金额写入出库单cost；根据ppid查询订单分解表，stat改为3，已出库数量oqt+=qt;当stat>1时，只修改发货单的信息（签收时间、地址、GPS、签收人等）
        TDeliver t = JSONObject.parseObject(json, TDeliver.class);
        if(t.getId()>0){//修改
            if(!updateById(t)){
                return JsonResult.error(ErrorCode.ERR_504);
            }
            if(prod!=null){
                // 收集所有需要查询的bn值
                Set<String> bns = new HashSet<>();
                List<TDeliverp> list=JSONObject.parseArray(prod,TDeliverp.class);
                for(TDeliverp tp:list){
                    tp.setPid(t.getId());
                    tp.setStat(t.getStat());
                    tp.setOid(t.getOid());
                    tp.setCbn(t.getCbn());
                    if(tp.getBn()!=null) bns.add(tp.getBn());
                }
                if(t.getStat()==1) {
                    // 批量查询库存信息
                    Map<String, TProdstock> stockMap = stockService.list(new QueryWrapper<TProdstock>().in("bn", bns))
                            .stream()
                            .collect(Collectors.toMap(TProdstock::getBn, stock -> stock));
                    List<TProdstock> stockList = new ArrayList<>();
                    List<Integer> ppids = new ArrayList<>();
                    for (TDeliverp tp : list) {
                        if (tp.getBn() != null) {
                            TProdstock t2 = stockMap.get(tp.getBn());
                            double cost = tp.getOqt() * t2.getAmount() / t2.getQt();
                            t2.setAmount(t2.getAmount() - cost);
                            t2.setQt(t2.getQt() - tp.getOqt());
                            t2.setPqt(t2.getPqt() - tp.getOqt());
                            tp.setCost(cost);
                            stockList.add(t2);
                        }
                        if(tp.getPpid()!=null){
                            ppids.add(tp.getPpid());
                        }
                        if(!ppids.isEmpty()){
                            QueryWrapper<TOrderp> qw = new QueryWrapper<>();
                            qw.in("id",ppids);
                            List<TOrderp> orderps = orderpService.list(qw);
                            for (TOrderp orderp : orderps) {
                                orderp.setOqt(orderp.getOqt()+tp.getOqt());
                                orderp.setStat(3);
                            }
                            if(!orderpService.updateBatchById(orderps)){
                                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚
                                return JsonResult.error(ErrorCode.ERR_504);
                            }
                       }
                    }
                    if(!stockService.updateBatchById(stockList)){
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚
                        return JsonResult.error(ErrorCode.ERR_504);
                    }
                }

                if(!deliverpService.updateBatchById(list)){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚
                    return JsonResult.error(ErrorCode.ERR_504);
                }
                t.setProd(list);
            }

        }else{//新增
            if(!save(t)){
                return JsonResult.error(ErrorCode.ERR_504);
            }
            if(prod!=null){
                List<TDeliverp> list=JSONObject.parseArray(prod,TDeliverp.class);
                for(TDeliverp tp:list){
                    tp.setPid(t.getId());
                    tp.setStat(t.getStat());
                    tp.setOid(t.getOid());
                    tp.setCbn(t.getCbn());
                    orderpMapper.updateOqt(tp.getPpid(),tp.getOqt()==null?0:tp.getOqt());
                }
                if(!deliverpService.saveBatch(list)){
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//回滚
                    return JsonResult.error(ErrorCode.ERR_504);
                }
                t.setProd(list);
            }


        }
        return JsonResult.success(t);
    }

    @Override
    public Object get(HttpServletRequest request, Integer id, String cbn, String oid, String stat) {
        QueryWrapper<TDeliver> qw=new QueryWrapper<>();
        if(id!=null){
            TDeliver t=getById(id);
            if(t==null){
                return JsonResult.error(ErrorCode.ERR_313);
            }
            t.setProd(deliverpService.list(new QueryWrapper<TDeliverp>().eq("pid",id)));
            return JsonResult.success(t);
        }else if(cbn!=null){
            qw.like("cbn",cbn);
            List<TDeliver> list=list(qw);
            setProdForOrders(list);
            return JsonResult.success(list);
        }else if(oid!=null){
            qw.like("oid",oid);
            List<TDeliver> list=list(qw);
            setProdForOrders(list);
            return JsonResult.success(list);
        }else if(stat!=null){
            if(stat.contains(",")){
                String[] ss=stat.split(",");
                for (int i = 0; i < ss.length; i++) {
                    if (i == 0) {
                        qw.eq("stat", ss[i]);
                    } else {
                        qw.or().eq("stat", ss[i]);
                    }
                }
            }else{
                qw.eq("stat",stat);
            }
            List<TDeliver> list=list(qw);
            setProdForOrders(list);
            return JsonResult.success(list);
        }

        return JsonResult.error(ErrorCode.ERR_200);
    }

    private void setProdForOrders(List<TDeliver> orders) {
        for (TDeliver t : orders) {
            t.setProd(deliverpService.list(new QueryWrapper<TDeliverp>().eq("pid", t.getId())));
        }
    }
}
